/**
    @author: ASUS
    @date: 2021/2/21
    @Describe:
**/
package kernel

import (
	"fmt"
	"log"
	"logprocess/global/monitor"
	"net/url"
	"regexp"
	"strconv"
	"strings"
	"time"
)

const TypeErrNum = iota + 1 //记录错误的行数

type Message struct {
	TimeLocal                    time.Time
	BytesSent                    int //流量
	Path, Method, Scheme, Status string
	UpstreamTime, RequestTime    float64
}

type LogProcess struct {
	Rc    chan []byte   //读取
	Wc    chan *Message //写入
	Read  Reader        //读取器
	Write Writer        //写入器
}

/**
正则匹配 出来的 0位置， 是本身 字符串

117.89.195.195 - - [19/Feb/2021:11:35:25 +0800] "GET / HTTP/1.1" 304 0 - "http://www.zxxtyzy.com/"
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63" "-" "0.000"

([\d\.]+)\s+                117.89.195.195
([^ \[]+)\s+				-
([^ \[]+)\s+				-
\[([^\[\]]+)\]\s+			19/Feb/2021:11:35:25 +0800
\"([^"]+)\"\s+				GET / HTTP/1.1
(\d{3})\s+(\d+)\s+			304
([^ \[]+)\s+				0
\"([^"]+)\"\s+				http://www.zxxtyzy.com/
\"([^"]+)\"\s+				Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63
\"(.*?)\"\s+				-
\"([\d\.-]+)\"				-           UpstreamTime
\"([\d\.-]+)\"				0.000		RequestTime

*/
func (l *LogProcess) Process() {
	//解析模块
	r := regexp.MustCompile(`([\d\.]+)\s+([^ \[]+)\s+([^ \[]+)\s+\[([^\[\]]+)\]\s+\"([^"]+)\"\s+(\d{3})\s+(\d+)\s+([^ \[]+)\s+\"([^"]+)\"\s+\"([^"]+)\"\s+\"(.*?)\"\s+\"([\d\.-]+)\"\s\"([\d\.-]+)\"`)

	for v := range l.Rc {
		ret := r.FindStringSubmatch(string(v))
		if len(ret) != 14 {
			monitor.TypeMonitorChan <- TypeErrNum
			log.Println("FindStringSubmatch fail:", string(v))
			continue
		}
		message := &Message{}
		fmt.Println(ret[4])
		t, err := time.ParseInLocation("02/Jan/2006:15:04:05 -0700", ret[4], time.Local) //转换时间格式
		if err != nil {
			monitor.TypeMonitorChan <- TypeErrNum
			log.Println("ParseInLocation fali: ", err.Error(), ret[4])
			continue
		}
		message.TimeLocal = t
		byteSent, _ := strconv.Atoi(ret[7])
		message.BytesSent = byteSent
		//GET / HTTP/1.1
		split := strings.Split(ret[5], " ")
		if len(split) != 3 {
			monitor.TypeMonitorChan <- TypeErrNum
			log.Println("strings.Splict fail", ret[5])
			continue
		}
		message.Method = split[0]
		u, err := url.Parse(split[1])
		if err != nil {
			monitor.TypeMonitorChan <- TypeErrNum
			log.Println("url.Parse fail ", err.Error())
			continue
		}
		message.Path = u.Path
		message.Scheme = split[2] //协议
		message.Status = ret[6]   //状态
		var upstreamTime float64
		if ret[12] != "-" {
			upstreamTime, _ = strconv.ParseFloat(ret[12], 64)
		}
		upstreamTime, _ = strconv.ParseFloat("0.000", 64)

		message.UpstreamTime = upstreamTime
		requestTime, _ := strconv.ParseFloat(ret[13], 64)
		message.RequestTime = requestTime

		l.Wc <- message

	}
}
